<?php
/*
使用形式：
$cache = new PageCache("cache/","index.html",10); 
if(!$cache->CheckCache()){//更新缓存
	ob_clean();
	ob_start();
	ob_implicit_flush(0);
	$a = 'content';
	...
	$length = ob_get_length();
	$content = ob_get_contents();
	$cache->UpdateCache($content,$length);
	ob_end_clean();
}
//直接访问html
header("location:www.abc.com/index.html");
*/
class PageCache{
	public $CacheDir = '';			/* 缓存目录 */
	public $CacheFileName = '';
	public $SetTimeOut = 0;			/* 缓存过期时间 */
	public $CacheFileUrl = ''; 		/* 缓存文件所在地址 */
	public $CacheConfigFile = '';	/* 缓存文件配置信息地址 */
	public $Cache = false;			/* 是否需要缓存，用户外界判断 */
	
	public $CacheRecord = false;	/*是否需要记录缓存信息*/
	public $LastUnixTimePoke = 0;	/* 上一次缓存的 Unix 时间戳 */
	public $CurrentUnixTimePoke = 0;/* 当前缓存的 Unix 时间戳 */
	public $NextUnixTimePoke = 0;	/* 下一次缓存的 Unix 时间戳 */
	public $UnixNowToNext = 0;		/* 现在和下一次缓存相差的 Unix 时间戳 */
	public $LastTimePoke = 0;		/* 上一次缓存的时间 */
	public $CurrentTimePoke = 0;	/* 当前缓存的时间 */
	public $NextTimePoke = 0;		/* 下一次缓存的时间 */
	
	public $DataLength = 0;			/* 缓存区内容长度 */
	public $CacheToPage = '';		/* 缓存文件内容 */
	
	public $Error = '';
	
	public function __construct($CacheDir = '', $CacheFileName = '', $SetTimeOut = 10, $CacheRecord = false){
		if($CacheDir == ''){
			$this->Error = '未设置缓存目录';
			return false;
		} else {
			$this->CacheDir = $CacheDir;
		}
		if($CacheFileName == ''){
			$this->Error = '未设置缓存文件';
			return false;
		} else {
			$this->CacheFileName = $CacheFileName;
		}	
		if(!is_numeric($SetTimeOut)){
			$this->Error = '缓存过期时间设置无效';
			return false;
		} else {
			$this->SetTimeOut = $SetTimeOut;
		}
		$this->CacheRecord = $CacheRecord;
		$this->CreateCache();
		return true;
	}
	
	private function CreateCache(){
		if($this->CacheRecord){//需要记录信息
			$_CacheConfig = substr($this->CacheFileName,0,-4).'config';
			$_CacheConfigUrl = $this->CacheDir.$_CacheConfig;
			if(!file_exists($_CacheConfigUrl)){
				if(!$hanld = fopen($_CacheConfigUrl,"w")){
					$this->Error = '不能创建文件'.$_CacheConfigUrl;
					return false;
				}
				@fclose($hanld);
			}
			$this->CacheConfigFile = $_CacheConfigUrl;
		}
		if(!file_exists($this->CacheDir)){
			if(!mkdir($this->CacheDir,0777)){
				$this->Error = '不能创建目录'.$this->CacheDir;
				return false;
			}
		}
		$_CacheUrl = $this->CacheDir.$this->CacheFileName;
		if(!file_exists($_CacheUrl)){
			if(!$hanld = @fopen($_CacheUrl,"w")){
				$this->Error = '不能创建文件'.$_CacheUrl;
				return false;
			}
			@fclose($hanld);
		}
		$this->CacheFileUrl = $_CacheUrl;
		return true;
	}
	
	public function CheckCache(){
		$_FileEditTime = @filemtime($this->CacheFileUrl);
		$_IsTimeOut = $_FileEditTime + $this->SetTimeOut;
		if($this->CacheRecord){
			$this->LastUnixTimePoke =$_FileEditTime;
			$this->NextUnixTimePoke =$_IsTimeOut;
			$this->CurrentUnixTimePoke = time();
			$this->UnixNowToNext = $this->NextUnixTimePoke - time();
			$this->LastTimePoke = date("Y-m-d H:i:s",$_FileEditTime);
			$this->NextTimePoke = date("Y-m-d H:i:s",$_IsTimeOut);
			$this->CurrentTimePoke = date("Y-m-d H:i:s",time());
			$_TxtInformation = "上次缓存时间戳: $this->LastUnixTimePoke".PHP_EOL;
			$_TxtInformation .= "当前缓存时间戳: $this->CurrentUnixTimePoke".PHP_EOL;
			$_TxtInformation .= "下次缓存时间戳: $this->NextUnixTimePoke".PHP_EOL;
			$_TxtInformation .= "上次缓存时间  : $this->LastTimePoke".PHP_EOL;
			$_TxtInformation .= "当前缓存时间  : $this->CurrentTimePoke".PHP_EOL;
			$_TxtInformation .= "下次缓存时间  : $this->NextTimePoke".PHP_EOL;
			$_TxtInformation .= "距离下次缓存戳: $this->UnixNowToNext";
			$handl = @fopen($this->CacheConfigFile,'w');
			if($handl){
				@fwrite($handl,$_TxtInformation);
				@fclose($handl);
			}
		}	
		if($_IsTimeOut >= time()){//在缓存期内
			return true;
		}else{//需要更新缓存
			return false;
		}
	}
	
	public function ClearCacheFile(){
		@unlink($this->CacheFileUrl);
		$this->CacheRecord && @unlink($this->CacheConfigFile);
	}
	
	public function UpdateCache($ob_content,$ob_lenth){
		$this->DataLength = $ob_lenth;
		$this->CacheToPage = $ob_content;	
		if(!file_exists($this->CacheFileUrl)){
			$CreateOK = $this->CreateCache();
			if(!$CreateOK){
				$this->Error = '检查缓存文件时产生错误，缓存文件创建失败';
				return false;
			}
		} else {
			$hanld = @fopen($this->CacheFileUrl,"w");
			if($hanld){
				if(@is_writable($this->CacheFileUrl)){
					@flock($hanld, LOCK_EX);
					$_PutData = @fwrite($hanld,$ob_content);
					@flock($hanld, LOCK_UN);
					if(!$_PutData){
						$this->Error = '无法更改当前缓存文件内容';
						return false;
					} else {
						@fclose($hanld);
						return true;
					}	
				}else {
					$this->Error = '缓存文件不可写';
					return false;
				}
			} else {
				$this->Error = '打开缓存文件发生致命错误';
				return false;
			}
		}
	}
	
	/**
	 * 返回缓存文件中的内容
	 *
	 * @return unknown
	 */
	public function GetCache(){
		$hanld = @fopen($this->CacheFileUrl,"r");
		if($hanld){
			if(@is_readable($this->CacheFileUrl)){
				$this->CacheToPage = @file_get_contents($this->CacheFileUrl);
				$IsEmpty = strlen($this->CacheToPage);//判断缓存文件是否为空
				if($IsEmpty > 0){
					return $this->CacheToPage;
					@fclose($hanld);
					exit();
				}
			} else {
				$this->Error = '读取缓存文件内容失败';
				return false;
			}
		} else {
			$this->Error = '打开缓存文件失败';
			return false;
		}
	}
	
	public function ErrResponse(){
		return $this->Error;
	}
}
?>